/**
 * 
 */
package it.unibo.refolding.common;

import java.io.Serializable;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;

import com.google.common.base.Preconditions;

public class IntPair implements Comparable<IntPair>, Serializable {

	private static final long serialVersionUID = 3660908850371688744L;

	public IntPair(int x, int y) {
		this.x = x;
		this.y = y;
	}

	public int compareTo(IntPair other) {
		if (x < other.x) {
			return -1;
		}
		if (x > other.x) {
			return +1;
		}
		if (y < other.y) {
			return -1;
		}
		if (y > other.y) {
			return +1;
		}
		return 0;
	}

	public final int x, y;

	@Override
	public String toString() {
		return ReflectionToStringBuilder.toString(this, ToStringStyle.SHORT_PREFIX_STYLE);
	}

	@Override
	public int hashCode() {
		return new HashCodeBuilder().append(x).append(y).toHashCode();
	}

	@Override
	public boolean equals(Object obj) {
		if (!(obj instanceof IntPair)) {
			return false;
		}
		IntPair other = (IntPair) obj;
		return x == other.x && y == other.y;
	}

	public static IntPair of(int x, int y) {
		return new IntPair(x, y);
	}

	public String repr() {
		return Integer.toString(x) + "," + Integer.toString(y);
	}
	
	public static IntPair eval(String s) {
		String[] a = StringUtils.split(s, ",");
		Preconditions.checkArgument(a.length == 2, s);
		return IntPair.of(Integer.parseInt(a[0]), Integer.parseInt(a[1]));
	}

	public static IntPair[] eval(String s, String prefix) {
		if (s.isEmpty()) {
			return new IntPair[0];
		}
		Preconditions.checkArgument(s.startsWith(prefix + '('));
		Preconditions.checkArgument(s.charAt(s.length() - 1) == ')');
		String[] a = StringUtils.splitByWholeSeparator(s.substring(prefix.length() + 1, s.length() - 1), separator(prefix));
		IntPair[] b = new IntPair[a.length];
		for (int i = 0; i < b.length; ++i) {
			b[i] = eval(a[i]);
		}
		return b;
	}

	private static String separator(String prefix) {
		return ")," + prefix + "(";
	}

	public static String repr(IntPair[] startSlopeAndPeakIndices, String prefix) {
		if (startSlopeAndPeakIndices.length == 0) {
			return "";
		} else {
			String[] s = new String[startSlopeAndPeakIndices.length];
			for (int i = startSlopeAndPeakIndices.length; --i >= 0; ) {
				s[i] = startSlopeAndPeakIndices[i].repr();
			}
			return prefix + '(' + StringUtils.join(s, separator(prefix)) + ')';
		}
	}
}
